package servlet;

import annotation.RequestMapping;
import com.alibaba.fastjson.JSON;
import controller.RepairController;
import lombok.SneakyThrows;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Kevin
 * @date 2020-12-29 19:15
 */
@WebServlet("/*")
public class BaseServlet extends HttpServlet {

    Map<String, Method> requestMapping;
    Map<Method, Object> instanceMapping;

    @Override
    public void init() throws ServletException {
        this.requestMapping = new HashMap<>();
        this.instanceMapping = new HashMap<>();
        // TODO 扫描controller包，拿到有注解的方法，这里暂时不写
        RepairController repairController = new RepairController();
        Method[] declaredMethods = RepairController.class.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            RequestMapping annotation = declaredMethod.getAnnotation(RequestMapping.class);
            if (annotation != null) {
                this.requestMapping.put(annotation.value(), declaredMethod);
                this.instanceMapping.put(declaredMethod, repairController);
            }
        }
    }

    @SneakyThrows
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String requestURI = req.getRequestURI();
        Method method = requestMapping.get(requestURI);
        Object responseObj = null;
        if (method != null) {
            Parameter[] parameters = method.getParameters();
            if (parameters.length == 1) {
                Object parameter = JSON.parseObject(req.getInputStream(), parameters[0].getType());
                Object instance = instanceMapping.get(method);
                responseObj = method.invoke(instance, parameter);
            } else {
                // TODO 多参数方法，暂时不写
            }
        } else {
            // TODO 这里假设匹配不上就是占位符url
            // 下面是随便写的，有的情况可能会出问题
            int index = requestURI.lastIndexOf('/');
            method = requestMapping.get(requestURI.substring(0, index) + "/{id}");
            if (method != null) {
                Object instance = instanceMapping.get(method);
                responseObj = method.invoke(instance, Integer.valueOf(requestURI.substring(index + 1)));
            } else {
                throw new RuntimeException("找不到controller...");
            }
        }
        byte[] bytes = JSON.toJSONBytes(responseObj);
        resp.setContentType("application/json");
        resp.getOutputStream().write(bytes);
    }

}
